
#import coords._pytpmmodule

b1950 = 2433282.42345905
j2000 = 2451545.0
CJ = 36525.0
CB = 36524.21987817305
s01 = 1
s02 = 2
s03 = 3
s04 = 4
s05 = 5
s06 = 6


# END of pytpm 



cimport c_numpy

c_numpy.import_array()

cimport c_coord_conv
from c_coord_conv cimport coord_conv_func, coord_conv_struct
from c_coord_conv cimport coord_conv_struct_new, coord_conv_struct_free
from c_coord_conv cimport fk5_gal, gal_fk5, fk5_fk4, fk4_fk5, gal_fk4, fk4_gal


from coord_system import FK5, FK4, GAL


cdef public class AstroCoordConvFunc[object PyAstroCoordConvFunctionObject,
                                     type PyAstroCoordConvFunctionType]:

    cdef object set(self,
                    coord_conv_func c_func, void *c_data,
                    void (*data_destr)(void *)):
        
        self.c_func = c_func 
        self.c_data = c_data
        self.data_destr = data_destr

        return self



_conv_map = {(FK5, FK4): AstroCoordConvFunc().set(<coord_conv_func> fk5_fk4,
                                                  NULL, NULL),
             (FK4, FK5): AstroCoordConvFunc().set(<coord_conv_func> fk4_fk5,
                                                  NULL, NULL),
             (FK5, GAL): AstroCoordConvFunc().set(<coord_conv_func> fk5_gal,
                                                  NULL, NULL),
             (GAL, FK5): AstroCoordConvFunc().set(<coord_conv_func> gal_fk5,
                                                  NULL, NULL),
             (FK4, GAL): AstroCoordConvFunc().set(<coord_conv_func> fk4_gal,
                                                  NULL, NULL),
             (GAL, FK4): AstroCoordConvFunc().set(<coord_conv_func> gal_fk4,
                                                  NULL, NULL),
             }



cdef class AstroCoordConv:
    cdef AstroCoordConvFunc _conv_func
    cdef object src
    cdef object dest
    cdef object epoch
    
    def __init__(self, src_system, dest_system, epoch=None):
        #cdef coord_conv_struct *s
        
        self.src = src_system
        self.dest = dest_system

        self.epoch = epoch

        self._conv_func = _conv_map[(src_system, dest_system)]
        


    def inverse_conv(self):
        return AstroCoordConv(self.dest, self.src, epoch=self.epoch)


    def __call__(self, ra, dec):
        """ ra, dec could be 1-d numpy array"""

        cdef coord_conv_func _conv_func
        cdef void *_conv_data

        cdef c_numpy.ndarray ra_old, dec_old 
        cdef c_numpy.ndarray ra_new, dec_new

        cdef double *ra_old_data, *dec_old_data 
        cdef double *ra_new_data, *dec_new_data
        cdef int i
        
        ra_old = c_numpy.PyArray_ContiguousFromAny(ra, c_numpy.NPY_DOUBLE, 1, 1)
        dec_old = c_numpy.PyArray_ContiguousFromAny(dec, c_numpy.NPY_DOUBLE, 1, 1)

        ra_new = c_numpy.PyArray_EMPTY(ra_old.nd, ra_old.dimensions,
                                       c_numpy.NPY_DOUBLE, 0)
        dec_new = c_numpy.PyArray_EMPTY(ra_old.nd, ra_old.dimensions,
                                        c_numpy.NPY_DOUBLE, 0)

        
        ra_old_data = <double *> c_numpy.PyArray_DATA(ra_old)
        dec_old_data = <double *> c_numpy.PyArray_DATA(dec_old)
        ra_new_data = <double *> c_numpy.PyArray_DATA(ra_new)
        dec_new_data = <double *> c_numpy.PyArray_DATA(dec_new)
        

        _conv_func = self._conv_func.c_func
        _conv_data = self._conv_func.c_data


        for i from 0 <= i < c_numpy.PyArray_SIZE(ra_new):
            _conv_func(ra_old_data[i], dec_old_data[i],
                       ra_new_data + i, dec_new_data + i,
                       _conv_data)

            
        return ra_new, dec_new

